@file:Suppress("RECEIVER_NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS")

package com.et.util

import android.content.Context
import android.text.TextUtils
import android.util.Log
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.util.zip.ZipEntry
import java.util.zip.ZipOutputStream

fun copyFromAssets(ctx: Context, assetsDir: String, destDir: File) {
    ctx.assets.list(assetsDir)?.let { strings ->
        if (strings.isNotEmpty()) {
            strings.forEach {
                ctx.assets.open("$assetsDir${File.separator}$it").use { input ->
                    val buf = ByteArray(4096)
                    FileOutputStream(File(destDir, it)).let { output ->
                        var l: Int
                        while (input.read(buf).apply {
                                l = this
                            } > 0) {
                            output.write(buf, 0, l)
                        }
                    }
                }
            }
        }
    }
}


fun File.deleteFile(): Boolean {
    return if (!this.exists()) {
        Log.d("deleteFile", this.name + " no exists!")
        false
    } else {
        if (this.isFile) deleteSingleFile() else deleteDirectory()
    }
}


fun File.deleteSingleFile(): Boolean {
    // 如果文件路径所对应的文件存在，并且是一个文件，则直接删除
    return if (this.exists() && this.isFile) {
        if (this.delete()) {
            Log.d("deleteSingleFile", this.name + " success!")
            true
        } else {
            Log.d("deleteSingleFile", this.name + " fail!")
            false
        }
    } else {
        Log.d("deleteSingleFile", this.name + " no exists!")
        false
    }
}


fun File.deleteDirectory(): Boolean {

    if (!this.exists() || !this.isDirectory) {
        Log.d("deleteDirectory", this.name + " no exists!")
        return false
    }
    var flag = true
    val files = this.listFiles()
    for (file in files) {
        if (file.isFile) {
            flag = file.deleteSingleFile()
            if (!flag) break
        } else if (file.isDirectory) {
            flag = file.deleteDirectory()
            if (!flag) break
        }
    }
    if (!flag) {
        Log.d("deleteDirectory", this.name + " fail!")
        return false
    }
    return if (this.delete()) {
        Log.d("deleteDirectory", this.name + " success!")
        true
    } else {
        Log.d("deleteDirectory", this.name + " fail!")
        false
    }
}

fun String.getFileExtensionFromUrl(): String {
    var tmp: String = this
    if (!TextUtils.isEmpty(tmp)) {
        val fragment = tmp.lastIndexOf('#')
        if (fragment > 0) {
            tmp = tmp.substring(0, fragment)
        }
        val query = tmp.lastIndexOf('?')
        if (query > 0) {
            tmp = tmp.substring(0, query)
        }
        val filenamePos = tmp.lastIndexOf('/')
        val filename = if (0 <= filenamePos) tmp.substring(filenamePos + 1) else tmp

        if (filename.isNotEmpty()
        ) {
            val dotPos = filename.lastIndexOf('.')
            if (0 <= dotPos) {
                return filename.substring(dotPos + 1)
            }
        }
    }
    return "unknown"
}

/**
 * 压缩文件和文件夹
 * @param srcFileString 要压缩的文件或文件夹
 * @param zipFileString 压缩完成的Zip路径
 * @throws Exception
 */
fun zipFolder(srcFileString: String, zipFileString: String) {
    // 创建ZIP
    val outZip = ZipOutputStream(FileOutputStream(zipFileString))
    // 创建文件
    val file = File(srcFileString)
    // 压缩
    zipFiles("${file.parent}${File.separator}", file.name, outZip)
    // 完成和关闭
    outZip.finish()
    outZip.close()
}

/**
 * 压缩文件
 *
 * @param folderString
 * @param fileString
 * @param zipOutputSteam
 * @throws Exception
 */
fun zipFiles(
    folderString: String,
    fileString: String,
    zipOutputSteam: ZipOutputStream?
) {
    if (zipOutputSteam == null) return
    val file = File(folderString + fileString)
    if (file.isFile) {
        val zipEntry = ZipEntry(fileString)
        val inputStream = FileInputStream(file)
        zipOutputSteam.putNextEntry(zipEntry)
        var len: Int
        val buffer = ByteArray(4096)
        while ((inputStream.read(buffer).also { len = it }) != -1) {
            zipOutputSteam.write(buffer, 0, len)
        }
        zipOutputSteam.closeEntry()
    } else {
        // 文件夹
        val fileList: Array<String>? = file.list()
        // 没有子文件和压缩
        if (fileList != null) {
            if (fileList.isEmpty()) {
                val zipEntry = ZipEntry(fileString + File.separator)
                zipOutputSteam.putNextEntry(zipEntry)
                zipOutputSteam.closeEntry()
            }
        }
        // 子文件和递归
        if (fileList != null) {
            for (i in fileList.indices) {
                zipFiles("$folderString$fileString/", fileList[i], zipOutputSteam)
            }
        }
    }
}